package com.cfw.queue;

import java.util.Scanner;


public class CircleQueueDemo {

	public static void main(String [] agrs) {
		
		Scanner scanerScanner = new Scanner(System.in);
		
		boolean loop = true;
		
		//有效数组空间为4-1
		CircleQueue queue = new CircleQueue(4);
		
		while (loop) {
			char key = scanerScanner.next().charAt(0);
			
			switch (key) {
				case 'a':
					System.out.println("请输入一个数");
					int num = scanerScanner.nextInt();
					queue.addQueue(num);
					break;
				case 'e':
					loop = false;
					break;
				case 's':
					queue.showQueue();
					break;
				case 'g':
					System.out.println(queue.getItem());
					break;
				case 'h':
					System.out.println(queue.getHead());
					break;
				default:
					break;
				}
			
		}
		
	}
	
	
	
	
}
/**
 * 通过数组模拟 环形队列,有效空间为构造数字
 * 
 * 可以采取环形数组，修改 front 和 rear 和 取模改进
 * maxSize  :比有效数组长度大于（可以解决 判断是否满队 bug）
 * front ： 队列最前面的元素
 * rear ：队列最后元素的下一位
 * 
 * 判断是否满队条件：(rear+1 )
 * 
  */

/**
 * 
 * @author Administrator
 * （1）使用maxsize 预留多一个空间，是为了解决队满之后，移除元素之后，还可以继续添加元素
 * 
 * 比如，maxsize =4 ，队满之后rear = 3 ，次数不能再添加元素，移除头元素后，front =1；
 * 次数判断队满为false，可以继续添加元素，到arr[rear] = arr[3] = 3
 * 是添加到队尾，符合队列后进后出的原则；
 * 如果没有预留到空间，只能往头部增加，不符合后进后出的原则
 */

class CircleQueue {
	private int maxSize;
	private int front = 0;
	private int rear = 0 ;
	private int array[];
	
	public CircleQueue(int maxSize) {
		this.maxSize = maxSize;
		array = new int[this.maxSize];
	
	}
	
	//判断队列是否为空
	public boolean isEmpty() {
		
		return this.rear == this.front;
		
	}
	
	//判断队列是否满了
	public boolean isFull() {
		return ((this.rear+1) % this.maxSize) == this.front;
	}
	
	//加元素
	public void addQueue(int item) {
		if (this.isFull()) {
			System.out.println("队列满了");
			return;
		}
		this.array[this.rear] = item;
		this.rear = (this.rear+1)%this.maxSize;
	}
	
	
	//出队列，移除队列
	public int getItem(){
		if(this.isEmpty()) {
			System.out.println("队列为空");
			return -1;
		}
		int tem =  this.array[this.front];
		this.front = (this.front+1)%this.maxSize;
		return tem;
	}
	
	//查看队头，不删除
	public int getHead() {
		if(this.isEmpty()) {
			System.out.println("队列为空");
			return -1;
		}
		return this.array[this.front];
	}
	
	//显示队列
	public void showQueue() {
		if(this.isEmpty()) {
			System.out.println("队列为空");
			return;
		}
	
		/**
		 * 这里有效个数不能直接 i < this.rear，如果出现队满后，删除了，就不等了
		 * 
		 * 因为i可能出现
		 * 因此需要修改
		 */
		
		//i%this.maxSize 需要考虑被移除的情况比如front 为3 ，rear 为1，i可能大于4
		for (int i = this.front; i <this.front+size() ; i++) {
			System.out.printf("arr[%d]=%d\t", i%this.maxSize,this.array[i%this.maxSize]);
		}
	}
	/**
	 * 需要考虑到队满之后的情况 ，因此先加上max 再取模就可以得到有效长度
	 * @return
	 * 
	 * 假设 maxSize 为 5，front 为 3，rear 为 1。
		(rear + maxSize - front) % maxSize = (1 + 5 - 3) % 5 = 3 % 5 = 3
		rear - front = 1 - 3 = -2（这不是有效的队列大小）
	 */
	int size() {
		return (this.rear + this.maxSize -this.front) % this.maxSize;
	}
}